package 查找算法.二分查找;

/**
 * @Project: data-structure-and-algorithms
 * @Package: 查找算法.二分查找
 * @ClassName: BinarySearch
 * @Author: zhouyihe
 * @Date: 2025/11/17 11:21
 * @Description: 二分查找
 * 优点:
 * 查找效率非常高，时间复杂度为 O(log n)
 * 在大规模数据集上表现优异
 * 实现相对简单
 * 不需要额外的空间（迭代实现）
 * 缺点:
 * 要求数据必须是有序的
 * 只适用于支持随机访问的数据结构（如数组）
 * 对于频繁插入和删除的数据结构，维护有序性的成本很高
 * 不适合小数据量的查找（这种情况下线性查找可能更快）
 */
public class BinarySearch {
    // 迭代实现
    public static int binarySearch(int[] arr, int target) {
        int left = 0;
        int right = arr.length - 1;

        while (left <= right) {
            // 避免整数溢出
            int mid = left + ((right - left) >> 1);

            // 找到目标值
            if (arr[mid] == target) {
                return mid;
            }
            // 在左半部分继续查找
            else if (arr[mid] > target) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }

        // 未查找到返回-1
        return -1;
    }

    // 递归实现
    public static int binarySearchRecursive(int[] arr, int target, int left, int right) {
        if (left > right) {
            return -1;
        }

        int mid = left + ((right - left) >> 1);

        if (target == arr[mid]) {
            return mid;
        } else if (target > arr[mid]) {
           return binarySearchRecursive(arr, target, mid + 1, right);
        } else {
           return binarySearchRecursive(arr, target, left, mid - 1);
        }
    }

    // 测试
    public static void main(String[] args) {
        int[] arr = {2, 3, 4, 10, 40, 50, 70, 80};
        int target = 12;

        // 迭代方法
        int result = binarySearch(arr, target);
        if (result == -1) {
            System.out.println("元素 " + target + " 不存在于数组中");
        } else {
            System.out.println("元素 " + target + " 在数组中的索引为 " + result);
        }

        // 递归方法
        result = binarySearchRecursive(arr, target, 0, arr.length - 1);
        if (result == -1) {
            System.out.println("元素 " + target + " 不存在于数组中");
        } else {
            System.out.println("元素 " + target + " 在数组中的索引为 " + result);
        }
    }
}
